/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.pipeparser.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Vector;

/**
 *
 * @author carlos
 */
public class MashupRepo {

    public Map<String, Composition> repo = new HashMap<String, Composition>();

    public Map<String, Vector> mappableComponents = new HashMap<String, Vector>();
    public Map<String, String> hashMappableParams = new HashMap<String, String>();

    public Map freqDFConn = new HashMap<String, Integer>();

    private String pipesPath = "";

    public MashupRepo(String pipesPath){
        this.pipesPath = pipesPath;
    }

    public void loadMappableParams(){
        
        hashMappableParams.put("createrss.title", "createrss");
        hashMappableParams.put("createrss.description", "createrss");
        hashMappableParams.put("createrss.link", "createrss");
        hashMappableParams.put("createrss.pubdate", "createrss");
        hashMappableParams.put("createrss.author", "createrss");
        hashMappableParams.put("createrss.guid", "createrss");
        hashMappableParams.put("createrss.mediaContentURL", "createrss");
        hashMappableParams.put("createrss.mediaContenType", "createrss");
        hashMappableParams.put("createrss.mediaContentWidth", "createrss");
        hashMappableParams.put("createrss.mediaContentHeight", "createrss");
        hashMappableParams.put("createrss.mediaThumbURL", "createrss");
        hashMappableParams.put("createrss.mediaContentWidth", "createrss");
        hashMappableParams.put("createrss.mediaContentHeight", "createrss");
        hashMappableParams.put("regex.conf.RULE.field", "regex");
        hashMappableParams.put("subelement.conf.path", "subelement");
        hashMappableParams.put("filter.conf.RULE.field", "filter");
        hashMappableParams.put("sort.conf.KEY.field", "sort");
        hashMappableParams.put("loop.conf.assign_to", "loop");
        hashMappableParams.put("unique.conf.field", "unique");
         
        
        Vector vCreateRss = new Vector();
        vCreateRss.add("createrss.conf.title");
        vCreateRss.add("createrss.conf.description");
        vCreateRss.add("createrss.conf.link");
        vCreateRss.add("createrss.conf.pubdate");
        vCreateRss.add("createrss.conf.author");
        vCreateRss.add("createrss.conf.guid");
        vCreateRss.add("createrss.conf.mediaContentURL");
        vCreateRss.add("createrss.conf.mediaContenType");
        vCreateRss.add("createrss.conf.mediaContentWidth");
        vCreateRss.add("createrss.conf.mediaContentHeight");
        vCreateRss.add("createrss.conf.mediaThumbURL");
        vCreateRss.add("createrss.conf.mediaContentWidth");
        vCreateRss.add("createrss.conf.mediaContentHeight");
        mappableComponents.put("createrss", vCreateRss);

        Vector vRegex = new Vector();
        vRegex.add("regex.conf.RULE.field");
        mappableComponents.put("regex", vRegex);

        Vector vSubelement = new Vector();
        vSubelement.add("subelement.conf.path");
        mappableComponents.put("subelement", vSubelement);

        Vector vFilter = new Vector();
        vFilter.add("filter.conf.RULE.field");
        mappableComponents.put("filter", vFilter);

        Vector vSort = new Vector();
        vSort.add("sort.conf.KEY.field");
        mappableComponents.put("sort", vSort);

        Vector vLoop = new Vector();
        vLoop.add("loop.conf.assign_to");
        mappableComponents.put("loop", vLoop);

        Vector vUnique = new Vector();
        vUnique.add("unique.conf.field");
        mappableComponents.put("unique", vUnique);

    }

    public void loadCompositions() throws FileNotFoundException{

            Map moduleTypes = new HashMap();

            String dirPath = pipesPath;
            File dir = new File(dirPath);

            String[] children = dir.list();


            if(children == null){
                System.out.println("Directory does not exists");
                System.exit(1);
            }

            for(int i = 0; i < children.length; i++){
                String filename = children[i];

                String filepath = "";

                if(filename.contains("pipe")){
                    filepath = dirPath + filename;
                }else{
                    continue;
                }




                File jsonFile = new File(filepath);
                BufferedReader reader = new BufferedReader(new FileReader(jsonFile));

                Pipe pipe = new Pipe(reader);

                Composition comp = new Composition(filename);

                //Listing of modules
                LinkedList modules = pipe.getModules();
                Iterator moduleIt = modules.iterator();
                //System.out.println("==Modules==");
                while(moduleIt.hasNext()){
                    Map module = (Map)moduleIt.next();
                    String type = (String)module.get("type");

                    if(!type.contains("pipe:"))
                        moduleTypes.put(type, type);

                    //System.out.println("Module type: " + module.get("type") + "(id: " + module.get("id") + ")");

                    //System.out.println(module.keySet().toString());

                    /*
                    if(module.get("conf") != null){

                        LinkedHashMap m = (LinkedHashMap)module.get("conf");

                        //System.out.println(m.keySet().toString());

                        if(m.get("RULE") != null){
                            //System.out.println(m.get("RULE").getClass());

                            if(m.get("RULE") instanceof LinkedList){
                                //System.out.println(m.get("RULE").toString());

                                LinkedList l = (LinkedList)m.get("RULE");

                                System.out.println("Cada elemento de la lista: " + l.get(0).getClass());
                            }
                        }
                    }
                    */

                    
                    Module m = new Module((String)module.get("id"), (String)module.get("type"),
                            (LinkedHashMap)module.get("conf"));
                    
                    comp.modules.put((String)module.get("id"), m);

                }



                //Listing of wires
                LinkedList wires = pipe.getWires();
                Iterator wiresIt = wires.iterator();
                //System.out.println("\n\n==Wires==");
                while(wiresIt.hasNext()){
                    Map wire = (Map)wiresIt.next();
                    //System.out.println("Wire from: " + wire.get("src") + " to " + wire.get("tgt"));

                    String from = wire.get("src").toString();
                    String to = wire.get("tgt").toString();

                    from = from.replaceAll("\\{", "");
                    from = from.replaceAll("\\}", "");
                    from = from.replaceAll(" ", "");

                    to = to.replaceAll("\\{", "");
                    to = to.replaceAll("\\}", "");
                    to = to.replaceAll(" ", "");

                    String fromPair[]   = from.split(",");
                    String fromParam[]  = fromPair[0].split("=");
                    String fromModule[] = fromPair[1].split("=");

                    String toPair[]   = to.split(",");
                    String toParam[]  = toPair[0].split("=");
                    String toModule[] = toPair[1].split("=");

                    Wire w = new Wire(fromModule[1], fromParam[1],
                            toModule[1], toParam[1]);
                    
                    String key = fromModule[1] +"=>" + toModule[1];

                    Vector v = comp.wires.get(key);

                    if(v == null){
                        v = new Vector<Wire>();
                    }

                    v.add(w);

                    comp.wires.put(key, v);
                    

                }

                repo.put(comp.id, comp);

            }

    }

    public void printRepoStatistics(){
        Iterator itRepo = (repo.keySet()).iterator();

        int countModules = 0;
        int countWires = 0;
        int countCompositions = 0;

        int countParams = 0;

        while(itRepo.hasNext()){

            countCompositions++;

            String key = (String)itRepo.next();
            Composition composition = repo.get(key);

            countModules += composition.modules.size();
            countWires += composition.wires.size();

            Iterator itMod = composition.modules.keySet().iterator();
            while(itMod.hasNext()){
                String keyMod = (String)itMod.next();
                Module module = composition.modules.get(keyMod);

                if(module.conf != null){
                    //countParams += module.conf.size();

                    Iterator itConf = module.conf.keySet().iterator();
                    while(itConf.hasNext()){
                        String keyConf = (String)itConf.next();
                        if(module.conf.get(keyConf) instanceof LinkedHashMap){
                            countParams++;
                        }else{
                            //System.out.println(module.conf.get(keyConf).getClass());
                            countParams += ((LinkedList)module.conf.get(keyConf)).size();
                        }
                    }
                }
            }
        }

        System.out.println("Avg modules: " + (double)countModules / (double)countCompositions);
        System.out.println("Avg wires..: " + (double)countWires / (double)countCompositions);
        System.out.println("Avg conf...: " + (double)countParams / (double)countModules);
        
        

    }

    public void printCompositions(){
        
        Iterator itRepo = (repo.keySet()).iterator();
        
        while(itRepo.hasNext()){
            String key = (String)itRepo.next();

            System.out.println("====== PIPE: " + key );

            Composition comp = repo.get(key);

            System.out.println("\t******* Modules:");

            Iterator itComp = comp.modules.keySet().iterator();
            while(itComp.hasNext()){
                String keyMod = (String)itComp.next();
                Module module = comp.modules.get(keyMod);

                System.out.println("\t" + keyMod + ": " + module.type);
                
            }

            System.out.println("\t####### Wires:");
            Iterator itWire = comp.wires.keySet().iterator();
            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);

                    System.out.println("\t" + w.toString());
                    
                }
                
            }

            
        }

    }

    public void printTxtItemsets(){
        Iterator itRepo = (repo.keySet()).iterator();

        while(itRepo.hasNext()){
            String key = (String)itRepo.next();
            Composition comp = repo.get(key);
            Iterator itWire = comp.wires.keySet().iterator();
            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);

                    //System.out.println("\t" + w.toString());
                    Module fromMod = comp.modules.get(w.fromModule);
                    Module toMod = comp.modules.get(w.toModule);

                    if((fromMod == null) || (toMod == null))
                        continue;

                    if((fromMod.type.contains("pipe")) || (toMod.type.contains("pipe")))
                        continue;
                    
                    System.out.println("{<" + fromMod.type + "." + w.fromPort + "->" +
                            toMod.type + "." + w.toPort + ">}");
                }

            }
            
            
        }
    }

    //This method computes the co-occurrence of dataflow connectors
    public void generateDfConnItemSetsARMiner(){
        Iterator itRepo = (repo.keySet()).iterator();
        Map<String, Integer> items = new HashMap<String, Integer>();
        Vector<GenericItem> vItems = new Vector<GenericItem>();
        int idx = 0;
        
        //Here we generate all the possible items (in this case, dataflow connectors)
        while(itRepo.hasNext()){
            String key = (String)itRepo.next();
            Composition comp = repo.get(key);
            Iterator itWire = comp.wires.keySet().iterator();
            
            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);
                    
                    Module fromMod = comp.modules.get(w.fromModule);
                    Module toMod = comp.modules.get(w.toModule);

                    if((fromMod == null) || (toMod == null))
                        continue;

                    if((fromMod.type.contains("pipe")) || (toMod.type.contains("pipe")))
                        continue;

                    String newItem = fromMod.type + "." + w.fromPort + "->" +
                            toMod.type + "." + w.toPort;

                    if(items.get(newItem) == null){
                        idx++;

                        GenericItem gi = new GenericItem();
                        gi.index = idx;
                        gi.name = newItem;
                        vItems.add(gi);

                        items.put(newItem, idx);
                    }                                        
                }
            }
        }

        Iterator itItems = vItems.iterator();

        while(itItems.hasNext()){
            GenericItem gi = (GenericItem)itItems.next();
            
            System.out.println(gi.index + " " + gi.name);
        }

        System.out.println("BEGIN");

        itRepo = (repo.keySet()).iterator();
        Vector<String> itemsets = new Vector<String>();
        while(itRepo.hasNext()){
            String key = (String)itRepo.next();
            Composition comp = repo.get(key);
            Iterator itWire = comp.wires.keySet().iterator();
            String itemset = "";

            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);

                    Module fromMod = comp.modules.get(w.fromModule);
                    Module toMod = comp.modules.get(w.toModule);

                    if((fromMod == null) || (toMod == null))
                        continue;

                    if((fromMod.type.contains("pipe")) || (toMod.type.contains("pipe")))
                        continue;

                    String newItem = fromMod.type + "." + w.fromPort + "->" +
                            toMod.type + "." + w.toPort;

                    int ind = items.get(newItem);

                    itemset = itemset + " " + ind;
                    
                }
            }

            System.out.println(itemset);
        }

        System.out.println("END");

    }


    public void getFrequentDataflowConn(double minSupp){
        Iterator itRepo = (repo.keySet()).iterator();
        Map<String, Integer> items = new HashMap<String, Integer>();
        Vector<GenericItem> vItems = new Vector<GenericItem>();
        int nbrCompositions = 0;

        //Here we generate all the possible items (in this case, dataflow connectors)
        while(itRepo.hasNext()){
            String key = (String)itRepo.next();
            
            Composition comp = repo.get(key);

            nbrCompositions++;

            //This is to control the repetition of a dataflow conn in a composition
            Map<String, String> repItemControl = new HashMap<String, String>();

            Iterator itWire = comp.wires.keySet().iterator();

            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);

                    Module fromMod = comp.modules.get(w.fromModule);
                    Module toMod = comp.modules.get(w.toModule);

                    if((fromMod == null) || (toMod == null))
                        continue;

                    if((fromMod.type.contains("pipe")) || (toMod.type.contains("pipe")))
                        continue;

                    String newItem = fromMod.type + "." + w.fromPort + "->" +
                            toMod.type + "." + w.toPort;

                    //Here we control that we do not count repetitions of dataflows in
                    //a composition (otherwise, the support of a dataflow can become
                    //bigger than 1).
                    String repItem = repItemControl.get(newItem);
                    if(repItem == null){
                        repItemControl.put(newItem, newItem);
                    }else{
                        continue;
                    }

                    Integer freq = items.get(newItem);
                    if(freq == null){
                        items.put(newItem, 1);
                    }else{
                        items.put(newItem, freq + 1);
                    }
                }
            }
        }

        System.out.println("###################");
        System.out.println("Dataflow Connectors");
        System.out.println("###################");
        System.out.println("Min. support: " +  minSupp + "\n");

        int count = 0;
        Iterator itItem = items.keySet().iterator();
        while(itItem.hasNext()){
            String key = (String)itItem.next();
            Integer freq = items.get(key);

            Double relSupp = (double)freq / (double)nbrCompositions;

            String strRelSupp = relSupp.toString();

            strRelSupp = strRelSupp.substring(0, 6);

            if(relSupp >= minSupp){
                count++;
                freqDFConn.put(key, freq);
                System.out.println(strRelSupp + "(" + freq + ")" + "\t" + key);
            }
        }

        System.out.println("\nTotal number of Dataflow Connectors: " + count);

    }

    //We mine datamappings that are associated with the frequent dataflow
    //connectors obtained with the method "public void getFrequentDataflowConn(double minSupp)"
    //Here we are supposed to use itemset mining, but since I have noticed that for each TYPE
    //of dataflow connector, there is only one TYPE of data mining, itemsets are of size one
    //only (at least for the dataset we use for the experiments in the WWW paper). So we use
    //just simple statistics to compute Data mapping patterns.
    public void mineDataMappings(double minsupp){
        this.loadMappableParams();
        Iterator itRepo = (repo.keySet()).iterator();
        Map<String, Integer> items = new HashMap<String, Integer>();
        Vector<GenericItem> vItems = new Vector<GenericItem>();

        Map<String, Integer> hashCompTypeCount = new HashMap<String, Integer>();

        Map<String, Vector> dmByCompType = new HashMap<String, Vector>();

        Map<String, Vector> assocDfDm = new HashMap<String, Vector>();

        //Here we generate all the possible items (in this case, dataflow connectors)
        while(itRepo.hasNext()){
            String key = (String)itRepo.next();

            Composition comp = repo.get(key);

            Iterator itWire = comp.wires.keySet().iterator();

            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);

                    Module fromMod = comp.modules.get(w.fromModule);
                    Module toMod = comp.modules.get(w.toModule);

                    if((fromMod == null) || (toMod == null))
                        continue;

                    if((fromMod.type.contains("pipe")) || (toMod.type.contains("pipe")))
                        continue;

                    String newItem = fromMod.type + "." + w.fromPort + "->" +
                            toMod.type + "." + w.toPort;

                    //We only find data mappings for frequent dataflow connectors
                    if(freqDFConn.get(newItem) != null){
                        
                        //We only consider data mappings for components that are
                        //mappable
                        if(mappableComponents.get(toMod.type) != null){
                            LinkedHashMap lhm = toMod.conf;                            

                            Iterator itLhm = lhm.keySet().iterator();

                            while(itLhm.hasNext()){
                                String keyLhm = (String)itLhm.next();

                                String compParam = toMod.type + ".conf." + keyLhm;

                                //Vector v = mappableParams.get(compParam);
                                if(hashMappableParams.get(compParam) != null){

                                    Integer count = hashCompTypeCount.get(compParam);
                                    if(count == null){
                                        hashCompTypeCount.put(compParam, 1);
                                    }else{
                                        hashCompTypeCount.put(compParam, ++count);
                                    }
                                    
                                    Vector v = dmByCompType.get(compParam);
                                    if(v == null){
                                        v = new Vector();
                                        dmByCompType.put(compParam, v);
                                    }

                                    LinkedHashMap m = (LinkedHashMap)lhm.get(keyLhm);
                                    String val = (String)m.get("value");
                                    v.add(val);

                                    Vector vAssig = (Vector)assocDfDm.get(newItem);
                                    if(vAssig == null){
                                        vAssig = new Vector();
                                        assocDfDm.put(newItem, vAssig);
                                    }
                                    String valAssig = compParam + "<=" + val;
                                    vAssig.add(valAssig);

                                    //System.out.println(compParam + "<=" + val);
                                }

                                //For those who include an array of values (RULE and KEY)
                                String compParamArray = compParam + ".field";
                                if(hashMappableParams.get(compParamArray) != null){
                                    //assocDfDm.put(newItem, compParamArray);
                                    
                                    Vector v = dmByCompType.get(compParamArray);
                                    if(v == null){
                                        v = new Vector();
                                        dmByCompType.put(compParamArray, v);
                                    }

                                    if(!(lhm.get(keyLhm) instanceof LinkedList))
                                        continue;
                                    
                                    LinkedList l = (LinkedList)lhm.get(keyLhm);

                                    Iterator itLl = l.iterator();
                                    while(itLl.hasNext()){
                                        LinkedHashMap eList = (LinkedHashMap)itLl.next();
                                        //System.out.println("field" + eList.get("field"));
                                        LinkedHashMap hField = (LinkedHashMap)eList.get("field");
                                        String value = (String)hField.get("value");

                                        v.add(value);

                                        Vector vAssig = (Vector)assocDfDm.get(newItem);
                                        if(vAssig == null){
                                            vAssig = new Vector();
                                            assocDfDm.put(newItem, vAssig);
                                        }
                                        String valAssig = compParam + "<=" + value;
                                        vAssig.add(valAssig);

                                        Integer count = hashCompTypeCount.get(compParamArray);
                                        if(count == null){
                                            hashCompTypeCount.put(compParamArray, 1);
                                        }else{
                                            hashCompTypeCount.put(compParamArray, ++count);
                                        }

                                    }

                                }


                            }

                        }

                    }                   
                }
            }
        }

        System.out.println("");
        System.out.println("###################");
        System.out.println("Data Mappings");
        System.out.println("###################");
        System.out.println("Min. Support: " + minsupp + "\n");

        //Here we compute the support for each type of DM
        Iterator itAssocDfDm = assocDfDm.keySet().iterator();
        while(itAssocDfDm.hasNext()){
            String key = (String)itAssocDfDm.next();
            Vector v = (Vector)assocDfDm.get(key);
            System.out.println("DATAFLOW CONNECTOR: " + key);

            HashMap<String, Integer> hashSupp = new HashMap<String, Integer>();
            int countTotal = v.size();
            for(int i = 0; i < v.size(); i++){

                Integer supp = hashSupp.get(v.get(i));
                if(supp == null){
                    hashSupp.put((String)v.get(i), 1);
                }else{
                    supp++;
                    hashSupp.put((String)v.get(i), supp);
                }
                
            }
            
            if(countTotal == 0)
                continue;


            Iterator itSupp = hashSupp.keySet().iterator();
            while(itSupp.hasNext()){
                String keySupp = (String)itSupp.next();
                Integer count = hashSupp.get(keySupp);
                double relSupp = (double)count / (double) countTotal;

                String strSupp = Double.toString(relSupp).substring(0, 4);
                if(relSupp >= minsupp)
                    System.out.println("\t" + strSupp + ": " + keySupp);
            }

        }

        /*

        System.out.println("========= Frequencies ===========");
        Iterator itHctc = hashCompTypeCount.keySet().iterator();
        while(itHctc.hasNext()){
            String key = (String)itHctc.next();

            System.out.println(key + ": " + hashCompTypeCount.get(key));
        }
         */
         



        /*
        System.out.println("========= Values ===========");
        Iterator itDm = dmByCompType.keySet().iterator();
        while(itDm.hasNext()){
            String key = (String)itDm.next();

            System.out.println("**" + key);

            Vector v = (Vector)dmByCompType.get(key);

            for(int i = 0; i < v.size(); i++){
                System.out.println("   " + v.get(i));
            }

        }
         */


        /*
        System.out.println("============= Assoc DF and DM =============");

        Iterator itAssocDfDm = assocDfDm.keySet().iterator();
        while(itAssocDfDm.hasNext()){
            String key = (String)itAssocDfDm.next();
            Vector v = (Vector)assocDfDm.get(key);
            System.out.println("DATAFLOW CONNECTOR: " + key);
            for(int i = 0; i < v.size(); i++){
                System.out.println("\t" + v.get(i));
            }

        }
         */
                               
    }

    public void mineParamValue(double minsupp){
        this.loadMappableParams();
        Iterator itRepo = (repo.keySet()).iterator();
        Map<String, Integer> items = new HashMap<String, Integer>();
        Vector<GenericItem> vItems = new Vector<GenericItem>();

        //Map<String, Integer> hashCompTypeCount = new HashMap<String, Integer>();

        //Map<String, Vector> dmByCompType = new HashMap<String, Vector>();

        //Map<String, Vector> assocDfDm = new HashMap<String, Vector>();

        Map<String, Vector> hashParamPerDF = new HashMap<String, Vector>();

        //Here we generate all the possible items (in this case, dataflow connectors)
        while(itRepo.hasNext()){
            String key = (String)itRepo.next();

            Composition comp = repo.get(key);

            Iterator itWire = comp.wires.keySet().iterator();

            while(itWire.hasNext()){
                String keyWire = (String)itWire.next();
                Vector vWires = comp.wires.get(keyWire);

                for(int i = 0; i < vWires.size(); i++){
                    Wire w = (Wire)vWires.get(i);

                    Module fromMod = comp.modules.get(w.fromModule);
                    Module toMod = comp.modules.get(w.toModule);

                    if((fromMod == null) || (toMod == null))
                        continue;

                    if((fromMod.type.contains("pipe")) || (toMod.type.contains("pipe")))
                        continue;

                    String newItem = fromMod.type + "." + w.fromPort + "->" +
                            toMod.type + "." + w.toPort;

                    
                    //We only find data mappings for frequent dataflow connectors
                    if(freqDFConn.get(newItem) != null){
                        //System.out.println(newItem);
                        
                            LinkedHashMap lhm = toMod.conf;

                            if(lhm == null)
                                continue;

                            Iterator itLhm = lhm.keySet().iterator();

                            String strItems = "";
                            while(itLhm.hasNext()){
                                String keyLhm = (String)itLhm.next();

                                String compParam = toMod.type + ".conf." + keyLhm;


                                String compParamArray = compParam + ".field";
                                if(hashMappableParams.get(compParamArray) != null)
                                    continue;

                                if(lhm.get(keyLhm) instanceof LinkedHashMap){
                                    LinkedHashMap hashVal = (LinkedHashMap)lhm.get(keyLhm);

                                    if(hashVal.get("value") instanceof LinkedHashMap)
                                        continue;

                                    
                                    String value = (String)hashVal.get("value");
                                    //System.out.println(hashVal.get("value"));

                                    //System.out.println(compParam + "<=" + value);

                                    strItems = strItems + "," + compParam + "<=" + value;

                                    
                                }
                               
                            }

                           if(strItems.equals(""))
                               continue;
                            
                           Vector v = hashParamPerDF.get(newItem);
                            if(v == null){
                                v = new Vector();
                                hashParamPerDF.put(newItem, v);
                            }

                            v.add(strItems);
                    }
                }
            }
        }

        /*
        Iterator it = hashParamPerDF.keySet().iterator();
        while(it.hasNext()){
            String key = (String)it.next();

            System.out.println(key);
            Vector v = hashParamPerDF.get(key);
            for(int i = 0; i < v.size(); i++){
                System.out.println("\t" + v.get(i));
            }
        }
         */

        Iterator it = hashParamPerDF.keySet().iterator();
        while(it.hasNext()){
            String key = (String)it.next();

            System.out.println(key);

            HashMap <String, Integer> hashIndex = new HashMap<String, Integer>();
            Vector vectorIndex = new Vector();

            Vector v = hashParamPerDF.get(key);
            int idx = 0;
            for(int i = 0; i < v.size(); i++){
                //System.out.println("\t" + v.get(i));
                String itemset = (String)v.get(i);
                String elems[] = itemset.split(",");

                for(int j = 1; j < elems.length; j++){
                    if(hashIndex.get(elems[j]) == null){
                        idx++;
                        vectorIndex.add(elems[j]);
                        hashIndex.put(elems[j], idx);
                    }
                }
                
            }

            for(int k = 0; k < vectorIndex.size(); k++){
                System.out.println((k+1) + "  " + vectorIndex.get(k));
            }

            System.out.println("BEGIN_DATA");
            Vector vData = hashParamPerDF.get(key);
            
            for(int i = 0; i < vData.size(); i++){
                //System.out.println("\t" + v.get(i));
                String itemset = (String)vData.get(i);
                String elems[] = itemset.split(",");

                for(int j = 1; j < elems.length; j++){
                    Integer index = (Integer)hashIndex.get(elems[j]);
                    System.out.print(index + " ");
                }
                System.out.println("");

            }
            System.out.println("END_DATA");

            /*
            Iterator itIdx = hashIndex.keySet().iterator();
            while(itIdx.hasNext()){
                String keyIdx = (String)itIdx.next();
                int val = (Integer)hashIndex.get(keyIdx);

                System.out.println("\t" + val + "  " + keyIdx);
            }
             */
        }

    }

    

}
